#ifndef __UTIL_H__
#define __UTIL_H__
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <time.h>
#include <sys/time.h>
#include <ctime>

class CTools
{
    public:
        static int64_t GetTickCount()
        {
            timeval timesnow;
            struct timezone tmpzone;
            gettimeofday(&timesnow,&tmpzone);
            return ((int64_t)(timesnow.tv_sec*1000) + (int64_t)(timesnow.tv_usec/1000));
        }

        static int GetUnixTime()
        {
            timeval timesnow;
            struct timezone tmpzone;
            gettimeofday(&timesnow,&tmpzone);
            return ((int)(timesnow.tv_sec));
        }

        static uint64_t GetUnixTimeMs()
        {
            timeval timesnow;
            gettimeofday(&timesnow, NULL);
            return (timesnow.tv_sec * 1000000 + timesnow.tv_usec);
        }
		
        /*获取今日年月日时间格式*/
		static int GetDateStr(std::string &str)
		{
			char now[64] = {0};
			time_t tt = time(NULL);
			struct tm *ttime;
			ttime = localtime(&tt);
			strftime(now, sizeof(now), "%Y%m%d", ttime); /*std::put_time(&tm, "%Y%m%d");*/
            str = now;
			return 0;
		}

        /*获取年月时间格式*/
        static int GetMonthStr(std::string &str)
        {
            char now[64] = {0};
            time_t tt = time(NULL);
            struct tm *ttime;
            ttime = localtime(&tt);
            strftime(now, sizeof(now), "%Y%m", ttime); /*std::put_time(&tm, "%Y%m%d");*/
            str = now;
            return 0;
        }

        /*获取昨日年月日时间格式*/
        static int GetYesterdayDateStr(std::string &str)
        {
            char now[64] = {0};
            time_t tt = time(NULL) - 24 * 60 * 60;
            struct tm *ttime;
            ttime = localtime(&tt);
            strftime(now, sizeof(now), "%Y%m%d", ttime); /*std::put_time(&tm, "%Y%m%d");*/
            str = now;
            return 0;
        }

        /*获取明天年月日时间格式*/
        static int GetTomorrowDateStr(std::string &str)
        {
            char now[64] = {0};
            time_t tt = time(NULL) + 24 * 60 * 60;
            struct tm *ttime;
            ttime = localtime(&tt);
            strftime(now, sizeof(now), "%Y%m%d", ttime); /*std::put_time(&tm, "%Y%m%d");*/
            str = now;
            return 0;
        }

        static int split_str(const char* ps_str, char* ps_sp, vector<std::string> &v_ret)
        {
            char* ps_temp;
            char* p;
            int i_len = (int)strlen(ps_str);
            std::string st_str;
            ps_temp = new char[i_len + 2];
            snprintf(ps_temp, i_len + 1, "%s", ps_str);
            char *last = NULL;    p = strtok_r(ps_temp, ps_sp, &last);
            if (NULL == p)
            {
                delete ps_temp;
                return 0;
            }
            st_str = (std::string)p;
            v_ret.push_back(st_str);
            while (NULL != (p = strtok_r(NULL, ps_sp, &last)))
            {
                st_str = (std::string)p;
                v_ret.push_back(st_str);
            }
            delete ps_temp;
            return 0;
        }

        static bool isSameDay(time_t time1, time_t time2)
        {
            return (((time1 + 28800) / 86400) == ((time2 + 28800) / 86400));
        }

        static bool isSameWeek(time_t time1, time_t time2)
        {
            std::tm* local_tm = std::localtime(&time1);
            int week1 = local_tm->tm_wday == 0 ?7:local_tm->tm_wday;
            int year_week1 = local_tm->tm_year + ((local_tm->tm_yday + 1) + 6 - week1) / 7;
            local_tm = std::localtime(&time2);
            int week2 = local_tm->tm_wday == 0 ?7:local_tm->tm_wday;
            int year_week2 = local_tm->tm_year + ((local_tm->tm_yday + 1) + 6 - week2) / 7;
            return year_week1 == year_week2;
        }

        static time_t getWeekFirstTimeStamp()
        {
            time_t t;
            t = time(0);
            tm *t_tm = localtime(&t);
            t_tm->tm_hour = 0;
            t_tm->tm_min = 0;
            t_tm->tm_sec = 0;
            t_tm->tm_mday = t_tm->tm_mday - t_tm->tm_wday + 1;
            t_tm->tm_wday = 0;
            t = mktime(t_tm);
            return t;
        }
        // 获取逗号之间的字符串
        static std::string getLastSubstring(const std::string str)
        {
            std::string result;
            size_t pos = str.find_last_of(",");
            if (pos != std::string::npos) {
                size_t startPos = pos + 1;
                size_t endPos = str.find_first_of(",", startPos);
                if (endPos == std::string::npos) {// 如果没有找到下一个逗号，则取字符串末尾位置
                    endPos = str.length();
                }
                result = str.substr(startPos, endPos - startPos); // 获取子串
            }
            if (!str.empty() && result.empty()) return str; // 如果找不到逗号，则返回整个字符串
            return result;
        }

        // 获取指定字符前后内容
        static void extractNumbers(const char* ps_sp, const std::string str, std::string& left, std::string& right)
        {
            size_t underscorePos = str.find(ps_sp);
            if (underscorePos != std::string::npos) 
            {
                left = str.substr(0, underscorePos); // 获取左边的子串
                right = str.substr(underscorePos + 1, str.length()); // 获取右边的子串
            }
            else
            {
                left = "";
                right = "";
            }
        }

        // 获取零点时间戳
        static std::time_t getMidnightTimestamp()
        {
            time_t t = time(NULL); 
            struct tm * tm= localtime(&t);  
            tm->tm_hour = 0;  
            tm->tm_min = 0;  
            tm->tm_sec = 0;  
            return mktime(tm);
        }

        static std::string replaceMark(const std::string& temp, const std::string& mark, const std::string& replaceStr)
        {
            size_t pos = temp.find(mark, 0);
            if(pos != std::string::npos){
                std::string result = "";
                std::string p1 = temp.substr(0, pos);
                result += p1;
                result += replaceStr;
                std::string p2 = temp.substr(pos+mark.length());
                result += p2;
                return result;
            }else{
                return std::string(temp);
            }
        }

        /*获取当前时间戳YY年MM月DD日*/
        static std::string GetDateKey(std::time_t date_time)
        {
            std::tm* t_tm = std::localtime(&date_time);
            t_tm->tm_hour = 0;
            t_tm->tm_min = 0;
            t_tm->tm_sec = 0;
            char strNow[64] = {0};
            strftime(strNow, sizeof(strNow), "%Y%m%d", t_tm);
            return std::string(strNow);
        }

        /*格式化时间戳*/
        static std::string FormatYMTime(std::time_t timeStamp)
        {
            struct tm *timeinfo = nullptr;
            char strNow[64] = {0};
            timeinfo = localtime(&timeStamp);
            strftime(strNow,sizeof(strNow),"%Y%m",timeinfo);
            return std::string(strNow);
        }
        static std::string FormatYMDTime(std::time_t timeStamp)
        {
            struct tm *timeinfo = nullptr;
            char strNow[64] = {0};
            timeinfo = localtime(&timeStamp);
            strftime(strNow,sizeof(strNow),"%Y%m%d",timeinfo);
            return std::string(strNow);
        }
        static std::string FormatDTime(std::time_t timeStamp)
        {
            struct tm *timeinfo = nullptr;
            char strNow[64] = {0};
            timeinfo = localtime(&timeStamp);
            strftime(strNow,sizeof(strNow),"%d",timeinfo);
            return std::string(strNow);
        }

        /*随机产生一个数的范围[a,b]*/
        static int Random(int a, int b)
        {
            return rand() % (b - a + 1) + a;
        }
};

#endif